package com.ztgf.commodity.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.ztgf.commodity.common.config.YmlConfig;
import com.ztgf.commodity.mapper.CategoryImportMapper;
import com.ztgf.commodity.models.bo.CategoryImportSaveBO;
import com.ztgf.commodity.models.dto.*;
import com.ztgf.commodity.models.service.*;
import com.ztgf.commodity.models.vo.CategoryAdminDetailsNewVO;
import com.ztgf.commodity.models.vo.CategoryBrandAttributesVO;
import com.ztgf.commodity.models.vo.CategoryBrandVO;
import com.ztgf.common.utils.CustomizeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import static com.ztgf.commodity.models.enums.CategoryImportUtil.*;

@Slf4j
@DubboService
public class CategoryImportServiceImpl extends ServiceImpl<CategoryImportMapper, CategoryImportDTO> implements ICategoryImportService {

    @Resource
    private YmlConfig ymlConfig;
    @DubboReference
    private ICategoryBrandAttributesRelationService categoryBrandAttributesRelationService;
    @DubboReference
    private ICommoditySpecificationService commoditySpecificationService;
    @DubboReference
    private ICommoditySpecificationAttrService commoditySpecificationAttrService;
    @DubboReference
    private ICommodityParamService commodityParamService;
    @DubboReference
    private ICommodityParamValueService commodityParamValueService;
    @DubboReference
    private ICommodityUnitService commodityUnitService;
    @DubboReference
    private ICommodityLabelService commodityLabelService;
    @DubboReference
    private ICommodityCategoryService commodityCategoryService;
    @DubboReference
    private IBrandInfoService brandInfoService;


    @Override
    public CategoryAdminDetailsNewVO importCategoryAttribute(byte[] input, Long id) {
        // 先查询类目
        CommodityCategoryDTO select = commodityCategoryService.selectById(id);
        if (select == null) {
            return null;
        }
        CategoryAdminDetailsNewVO result = new CategoryAdminDetailsNewVO();
        result.setId(select.getId());
        result.setCategoryName(select.getName());
        result.setSort(select.getSort());
        result.setIsDisplayNavBar(select.getIsPublish());
        result.setParentId(select.getParentId());
        // 解析excel
        // 将文件byte转成inputStream
        ByteArrayInputStream inputStream = new ByteArrayInputStream(input);
        try {
            Workbook workbook = WorkbookFactory.create(inputStream);
            inputStream.close();
            // 获取工作表对象
            Sheet sheet = workbook.getSheetAt(0);
            // 获取Excel表格中数据的行数
            int totalRow = sheet.getPhysicalNumberOfRows();
            // 获取Excel表格中数据的列数
            int totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
            // 第一行
            Row oneRow = sheet.getRow(0);
            // 整个表格的数据
            List<CategoryImportSaveBO> list = new ArrayList<>();
            for (int i = 1; i <= totalRow; i++) {
                // 行
                Row row = sheet.getRow(i);
                // 若有空行继续下一行（因为EXCEL有空行时报错故加上此代码）
                if (null == row || "".equals(row)) {
                    totalRow--;
                    continue;
                }
                String check = this.getCellValue(row.getCell(0));
                if (CustomizeUtil.strIsNull(check)) {
                    totalRow--;
                    continue;
                }
                // 一行的数据
                CategoryImportSaveBO rowObject = new CategoryImportSaveBO();
                for (int j = 0; j <= totalCells; j++) {
                    // 获取标题
                    String title = this.getCellValue(oneRow.getCell(j)).trim();
                    // 获取单元格值
                    String value = this.getCellValue(row.getCell(j)).trim();
                    if (CustomizeUtil.strIsNotNull(value)) {
                        switch (title) {
                            case ORDER_NUMBER:
                                rowObject.setOrderNumber(value);
                                break;
                            case BRAND:
                                rowObject.setBrandName(value);
                                break;
                            case UNIT:
                                rowObject.setUnits(value);
                                break;
                            case SALES_ATTRIBUTES:
                                rowObject.setSales(value);
                                break;
                            case PARAM_ATTRIBUTES:
                                rowObject.setParameter(value);
                                break;
                            case LABEL_ATTRIBUTES:
                                rowObject.setLabels(value);
                                break;
                            default:
                                break;
                        }
                    }
                }
                list.add(rowObject);
            }
            // TODO 处理解析后的数据
            List<CategoryBrandVO> listA = this.getImportDate(list, select);
            if (CustomizeUtil.listIsNotNull(listA)) {
                result.setBrandList(listA);
            }
            return result;
        } catch (Exception e) {
            log.info("导入属性的错误信息:{}", e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @Description: 处理解析后的数据
     * @Author: chenyu.wang
     * @Params: [list, category]
     * @Date: 2020.12.31 11:12
     */
    private List<CategoryBrandVO> getImportDate(List<CategoryImportSaveBO> list, CommodityCategoryDTO category) {
        if (CustomizeUtil.listIsNull(list)) {
            return null;
        }
        List<CategoryBrandVO> result = new ArrayList<>();
        for (CategoryImportSaveBO bo : list) {
            // 检查品牌
            CategoryBrandVO brand = brandInfoService.checkBrand(bo.getBrandName());
            // 检查单位
            if (CustomizeUtil.strIsNotNull(bo.getUnits())) {
                List<CategoryBrandAttributesVO> listA = this.getUnitDate(bo.getUnits(), category.getName(), brand.getBrandName());
                brand.setUnitIds(listA);
            }
            // 检查销售属性
            if (CustomizeUtil.strIsNotNull(bo.getSales())) {
                List<CategoryBrandAttributesVO> listB = this.getSalesAttributesDate(bo.getSales(), category.getName(), brand.getBrandName());
                brand.setSpecificationIds(listB);
            }
            // 检查参数属性
            if (CustomizeUtil.strIsNotNull(bo.getParameter())) {
                List<CategoryBrandAttributesVO> listC = this.getParameterAttributes(bo.getParameter(), category.getName(), brand.getBrandName());
                brand.setParamIds(listC);
            }
            //检查标签属性
            if (CustomizeUtil.strIsNotNull(bo.getLabels())) {
                List<CategoryBrandAttributesVO> listD = this.getTagAttributes(bo.getLabels(), category.getName(), brand.getBrandName());
                brand.setLabelList(listD);
            }
            result.add(brand);
        }
        return result;
    }


    /**
     * @Description: 检查标签属性
     * @Author: chenyu.wang
     * @Params: [tag, categoryName, brandName]
     * @Date: 2020.12.31 15:06
     */
    @Override
    public List<CategoryBrandAttributesVO> getTagAttributes(String tag, String categoryName, String brandName) {
        List<CategoryBrandAttributesVO> result = new ArrayList<>();
        HashSet<Long> idSet = new HashSet<>();
        // 备注
        String note = categoryName + " " + brandName;
        // 标签属性用中文分号隔开
        String[] tagArray = tag.split(";");
        for (String tagOne : tagArray) {
            Long id = ymlConfig.getPkId();
            // 查询标签是否存在
            Wrapper<CommodityLabelDTO> wrapper = new EntityWrapper<>();
            wrapper.eq("name", tagOne);
            CommodityLabelDTO selectOne = commodityLabelService.selectOne(wrapper);
            if (selectOne == null) {
                CommodityLabelDTO insertDto = new CommodityLabelDTO();
                insertDto.setName(tagOne);
                insertDto.setStatus(0);
                insertDto.setNotes(note);
                insertDto.setId(id);
                boolean insert = commodityLabelService.insert(insertDto);
                if (!insert) {
                    throw new RuntimeException("导入属性时添加标签失败");
                }
                boolean add = idSet.add(id);
                if (add) {
                    CategoryBrandAttributesVO voA = new CategoryBrandAttributesVO();
                    voA.setId(id);
                    voA.setAttributesName(tagOne);
                    voA.setNotes(note);
                    result.add(voA);
                }
            } else {
                boolean add = idSet.add(selectOne.getId());
                if (add) {
                    CategoryBrandAttributesVO voB = new CategoryBrandAttributesVO();
                    voB.setId(selectOne.getId());
                    voB.setAttributesName(selectOne.getName());
                    if (CustomizeUtil.strIsNotNull(selectOne.getNotes())) {
                        voB.setNotes(selectOne.getNotes());
                    }
                    result.add(voB);
                }
            }
        }
        return result;
    }

    /**
     * @Description: 检查参数
     * @Author: chenyu.wang
     * @Params: [parameter, categoryName, brandName]
     * @Date: 2020.12.31 14:52
     */
    @Override
    public List<CategoryBrandAttributesVO> getParameterAttributes(String parameter, String categoryName, String brandName) {
        List<CategoryBrandAttributesVO> result = new ArrayList<>();
        HashSet<Long> idSet = new HashSet<>();
        // 备注
        String note = categoryName + " " + brandName;
        // 处理录入的数据，多个参数用中文的分号隔开
        String[] paramArray = parameter.split(";");
        for (String param : paramArray) {
            log.info("导入的参数属性:{}", param);
            // 新增时的参数id
            Long id = ymlConfig.getPkId();
            // 一个参数和值之间用中文的冒号隔开
            String[] oneParam = param.split("：");
            // 参数名称
            String paramName = oneParam[0];
            // 参数值
            String[] valueArray = oneParam[1].split(",");
            // 先查询是否存在
            Wrapper<CommodityParamDTO> wrapper = new EntityWrapper<>();
            wrapper.eq("param_name", paramName).eq("notes", note);
            CommodityParamDTO selectOne = commodityParamService.selectOne(wrapper);
            if (selectOne == null) {
                CommodityParamDTO insertDto = new CommodityParamDTO();
                insertDto.setParamName(paramName);
                insertDto.setStatus(0);
                insertDto.setIsPublish(1);
                insertDto.setNotes(note);
                insertDto.setId(id);
                boolean insert = commodityParamService.insert(insertDto);
                if (!insert) {
                    throw new RuntimeException("导入属性时添加参数属性失败");
                }
                // 新添加值
                for (String va : valueArray) {
                    CommodityParamValueDTO insertB = new CommodityParamValueDTO();
                    insertB.setParamId(id);
                    insertB.setValueName(va);
                    insertB.setId(ymlConfig.getPkId());
                    commodityParamValueService.insert(insertB);
                }
                boolean add = idSet.add(id);
                if (add) {
                    CategoryBrandAttributesVO voA = new CategoryBrandAttributesVO();
                    voA.setId(id);
                    voA.setAttributesName(paramName);
                    voA.setNotes(note);
                    result.add(voA);
                }
            } else {
                for (String vb : valueArray) {
                    Wrapper<CommodityParamValueDTO> wrapperB = new EntityWrapper<>();
                    wrapperB.eq("param_id", selectOne.getId()).eq("value_name", vb);
                    CommodityParamValueDTO oneA = commodityParamValueService.selectOne(wrapperB);
                    if (oneA == null) {
                        CommodityParamValueDTO insertC = new CommodityParamValueDTO();
                        insertC.setParamId(selectOne.getId());
                        insertC.setValueName(vb);
                        insertC.setId(ymlConfig.getPkId());
                        commodityParamValueService.insert(insertC);
                    }
                }
                boolean add = idSet.add(selectOne.getId());
                if (add) {
                    CategoryBrandAttributesVO voB = new CategoryBrandAttributesVO();
                    voB.setId(selectOne.getId());
                    voB.setAttributesName(selectOne.getParamName());
                    if (CustomizeUtil.strIsNotNull(selectOne.getNotes())) {
                        voB.setNotes(note);
                    }
                    result.add(voB);
                }
            }
        }
        return result;
    }

    /**
     * @Description: 检查销售属性
     * @Author: chenyu.wang
     * @Params: [sales, categoryName, brandName]
     * @Date: 2020.12.31 14:36
     */

    public List<CategoryBrandAttributesVO> getSalesAttributesDate(String sales, String categoryName, String brandName) {
        List<CategoryBrandAttributesVO> result = new ArrayList<>();
        HashSet<Long> idSet = new HashSet<>();
        // 备注
        String note = categoryName + " " + brandName;
        // 处理录入的数据，用中文分号隔开
        String[] saleArray = sales.split(";");
        for (String sale : saleArray) {
            // 属性id
            Long id = ymlConfig.getPkId();
            // 属性和值之间用中文的冒号隔开
            String[] oneSale = sale.split("：");
            // 属性名称
            String attribute = oneSale[0];
            // 值处理值,值直接用中文的逗号隔开
            String[] valueArray = oneSale[1].split(",");
            // 根据名称和备注查询是否存在
            Wrapper<CommoditySpecificationDTO> wrapper = new EntityWrapper<>();
            wrapper.eq("name", attribute).eq("notes", note);
            CommoditySpecificationDTO selectOne = commoditySpecificationService.selectOne(wrapper);
            if (selectOne == null) {
                // 新增属性
                CommoditySpecificationDTO insertDto = new CommoditySpecificationDTO();
                insertDto.setName(attribute);
                insertDto.setStatus(0);
                insertDto.setIsPublish(1);
                insertDto.setNotes(note);
                insertDto.setId(id);
                boolean insert = commoditySpecificationService.insert(insertDto);
                if (!insert) {
                    throw new RuntimeException("导入属性时添加销售属性失败");
                }
                // 处理值,值直接用中文的逗号隔开
                for (String va : valueArray) {
                    // 新增属性值
                    CommoditySpecificationAttrDTO insertA = new CommoditySpecificationAttrDTO();
                    insertA.setSpecificationId(id);
                    insertA.setAttrName(va);
                    insertA.setStatus(0);
                    insertA.setIsPublish(1);
                    insertA.setId(ymlConfig.getPkId());
                    commoditySpecificationAttrService.insert(insertA);
                }
                boolean add = idSet.add(id);
                if (add) {
                    CategoryBrandAttributesVO vo = new CategoryBrandAttributesVO();
                    vo.setId(id);
                    vo.setAttributesName(attribute);
                    vo.setNotes(note);
                    result.add(vo);
                }
            } else {
                for (String vb : valueArray) {
                    Wrapper<CommoditySpecificationAttrDTO> wrapperA = new EntityWrapper<>();
                    wrapperA.eq("specification_id", selectOne.getId()).eq("attr_name", vb);
                    CommoditySpecificationAttrDTO selectOneA = commoditySpecificationAttrService.selectOne(wrapperA);
                    if (selectOneA == null) {
                        CommoditySpecificationAttrDTO insertB = new CommoditySpecificationAttrDTO();
                        insertB.setSpecificationId(selectOne.getId());
                        insertB.setAttrName(vb);
                        insertB.setStatus(0);
                        insertB.setIsPublish(1);
                        insertB.setId(ymlConfig.getPkId());
                        commoditySpecificationAttrService.insert(insertB);
                    }
                }
                boolean add = idSet.add(selectOne.getId());
                if (add) {
                    CategoryBrandAttributesVO voA = new CategoryBrandAttributesVO();
                    voA.setId(selectOne.getId());
                    voA.setAttributesName(selectOne.getName());
                    if (CustomizeUtil.strIsNotNull(selectOne.getNotes())) {
                        voA.setNotes(selectOne.getNotes());
                    }
                    result.add(voA);
                }
            }
        }
        return result;
    }

    /**
     * @Description: 检查导入的单位
     * @Author: chenyu.wang
     * @Params: [units, categoryName, brandName]
     * @Date: 2020.12.31 11:16
     */
    public List<CategoryBrandAttributesVO> getUnitDate(String units, String categoryName, String brandName) {
        List<CategoryBrandAttributesVO> result = new ArrayList<>();
        HashSet<Long> idSet = new HashSet<>();
        // 备注
        String note = categoryName + " " + brandName;
        // 多个用中文分号隔开
        String[] unitArray = units.split(";");
        for (String unit : unitArray) {
            // 根据名称查询是否存在
            Wrapper<CommodityUnitDTO> wrapper = new EntityWrapper<>();
            wrapper.eq("name", unit);
            CommodityUnitDTO selectOne = commodityUnitService.selectOne(wrapper);
            if (selectOne == null) {
                Long id = ymlConfig.getPkId();
                CommodityUnitDTO insertDto = new CommodityUnitDTO();
                insertDto.setName(unit);
                insertDto.setStatus(0);
                insertDto.setIsPublish(1);
                insertDto.setNotes(note);
                insertDto.setId(id);
                boolean insert = commodityUnitService.insert(insertDto);
                if (insert) {
                    boolean add = idSet.add(id);
                    if (add) {
                        CategoryBrandAttributesVO vo = new CategoryBrandAttributesVO();
                        vo.setId(id);
                        vo.setAttributesName(unit);
                        vo.setNotes(note);
                        result.add(vo);
                    }
                } else {
                    throw new RuntimeException("导入属性时添加品牌失败");
                }
            } else {
                boolean add = idSet.add(selectOne.getId());
                if (add) {
                    CategoryBrandAttributesVO voA = new CategoryBrandAttributesVO();
                    voA.setId(selectOne.getId());
                    voA.setAttributesName(selectOne.getName());
                    if (CustomizeUtil.strIsNotNull(selectOne.getNotes())) {
                        voA.setNotes(selectOne.getNotes());
                    }
                    result.add(voA);
                }
            }
        }
        return result;
    }


    private String getCellValue(Cell cell) {
        String cellValue = "";
        if (cell == null) {
            return cellValue;
        }
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_STRING:
                cellValue = cell.getStringCellValue().trim();
                break;
            case Cell.CELL_TYPE_NUMERIC:
                DecimalFormat df = new DecimalFormat("0");

                cellValue = df.format(cell.getNumericCellValue());
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_FORMULA:
                cellValue = cell.getCellFormula();
                break;
            default:
                cellValue = "";
        }
        return cellValue;
    }
}
